home *** CD-ROM | disk | FTP | other *** search
- TITLE POLYPROC - POLY-PROCESSING PIPELINE IN ASSEMBLER
-
- COMMENT $
-
- // 26/12/93 by Dave Stampe
- // All algorithms and code (c) 1993 by Dave Stampe
-
- /*
- This code is part of the REND386 project, created by Dave Stampe and
- Bernie Roehl.
-
- Copyright 1992, 1993, 1994 by Dave Stampe and Bernie Roehl.
-
- May be freely used to write software for release into the public domain;
- all commercial endeavours MUST contact BOTH Bernie Roehl and Dave Stampe
- for permission to incorporate any part of this software into their
- products! Usually there is no charge for under 50-100 items for
- low-cost or shareware, and terms are reasonable. Any royalties are used
- for development, so equipment is often acceptable payment.
-
- ATTRIBUTION: If you use any part of this source code or the libraries
- in your projects, you must give attribution to REND386, Dave Stampe,
- and Bernie Roehl in your documentation, source code, and at startup
- of your program. Let's keep the freeware ball rolling! No more
- code ripoffs please.
-
- CONTACTS: dstampe@psych.toronto.edu, broehl@sunee.uwaterloo.ca
- See the COPYRITE.H file for more information.
- */
-
- This file includes parts of the poly processing pipeline, including
- transformation and clipping. It also computes the poly depth for sorting,
- and does the backfacing poly math
-
- /* Contact: dstampe@sunee.waterloo.edu */
-
- $
-
- .MODEL large
- .386
-
- .DATA
-
- include 3dstruct.inc
- include viewdata.inc
- include rendmem.inc
-
- .CODE RENDERER
-
- ;/***************** XY VERTEX TRANSFORM -> CAMERA COORDS ************/
-
- ;/* X, Y viewport xform, create new vertex copy if needed */
- ;/* can reuse previously transformed vertices */
-
- ; NVERTEX *xy_transform(VERTEX *v)
-
- v equ DWORD PTR [bp+8] ; arguments
-
- wx equ DWORD PTR [bp-4] ; locals
- wy equ DWORD PTR [bp-8]
- wz equ DWORD PTR [bp-12]
-
- PUBLIC _xy_transform
-
- _xy_transform proc far
-
- .386
- push ebp
- mov ebp,esp
- sub esp,20
-
- push esi
- push edi
- push ecx
-
- les bx,v
- mov eax,es:[bx].V_nvptr ; is there an old copy available?
- test eax,-1
- jnz ptr_in_eax
-
- ALLOCVTX ; returns new vertex in es:bx
- ; also in _nvalloc
-
- les bx,DWORD PTR v
-
- mov eax,DWORD PTR es:[bx].V_x
- sub eax,DWORD PTR _VS_iview_x
- mov DWORD PTR wx,eax
-
- mov eax,DWORD PTR es:[bx].V_y
- sub eax,DWORD PTR _VS_iview_y
- mov DWORD PTR wy,eax
-
- mov eax,DWORD PTR es:[bx].V_z
- sub eax,DWORD PTR _VS_iview_z
- mov DWORD PTR wz,eax
-
- mov eax,DWORD PTR _VS_sfac1
- mov edx,DWORD PTR wx
- imul edx
- mov esi,eax
- mov edi,edx
-
- mov eax,DWORD PTR _VS_sfac2
- mov edx,DWORD PTR wy
- imul edx
- add esi,eax
- adc edi,edx
-
- mov eax,DWORD PTR _VS_sfac3
- mov edx,DWORD PTR wz
- imul edx
- add esi,eax
- adc edi,edx
-
- shrd esi,edi,27; 29-PRESCALE
- adc esi,0
- mov ecx,esi
-
- mov eax,DWORD PTR _VS_sfac4
- mov edx,DWORD PTR wx
- imul edx
- mov esi,eax
- mov edi,edx
-
- mov eax,DWORD PTR _VS_sfac5
- mov edx,DWORD PTR wy
- imul edx
- add esi,eax
- adc edi,edx
-
- mov eax,DWORD PTR _VS_sfac6
- mov edx,DWORD PTR wz
- imul edx
- add esi,eax
- adc edi,edx
-
- shrd esi,edi,27; 29-PRESCALE
- adc esi,0
- mov eax,esi
-
- mov esi,_nvalloc
- mov DWORD PTR es:[bx].V_nvptr,esi
-
- mov esi,DWORD PTR es:[bx].V_cz ;/* copy z (conv before) */
-
- les bx, _nvalloc
- mov DWORD PTR es:[bx].NV_x,ecx ;/* new x,y */
- mov DWORD PTR es:[bx].NV_y,eax
- mov DWORD PTR es:[bx].NV_z,esi
-
- mov eax,_nvalloc
-
- ptr_in_eax:
- shld edx,eax,16
-
- pop ecx
- pop edi
- pop esi
-
- mov esp,ebp
- pop ebp
- ret
-
- _xy_transform endp
-
-
-
- ;/********** PERSPECTIVE AND SCREEN CONVERT VERTEX ************/
-
- ; /* final processing for vertex passed */
- ; void *z_output(NVERTEX *nv) /* by clipper. Figure perspective */
- ; /* screen positions and poly outcodes */
- ; return soutcode
-
- nv equ DWORD PTR [bp+8] ; arguments
-
- PUBLIC _z_output
-
- _z_output proc far
-
- .386
- push ebp
- mov ebp,esp
-
- push ecx
- push edx
-
- les bx,DWORD PTR nv ; is perspective done yet?
- test BYTE PTR es:[bx].NV_persp,80h
- jne skip_perspective
-
- mov cl,BYTE PTR _VS_xshift ; prescale x, y for accuracy */
-
- mov eax,DWORD PTR es:[bx].NV_x
- cdq
- shld edx,eax,cl
- shl eax,cl
- idiv DWORD PTR es:[bx].NV_z ;/* divide by z
- add eax,DWORD PTR _VS_hsc ;/* add prescaled screen center */
- and eax,0FFFFFFFCh ;/* lock to integer */;
- mov DWORD PTR es:[bx].NV_xs,eax ;/* and store */
-
- xor ch,ch
- cmp eax,DWORD PTR _VS_right4
- jle nsro ;/* check outcodes */
- or ch,ORIGHT
- nsro:
- cmp eax,DWORD PTR _VS_left4
- jge nslo
- or ch,OLEFT
- nslo:
- mov cl,BYTE PTR _VS_yshift; ; same deal for y */
-
- mov eax,DWORD PTR es:[bx].NV_y
- cdq
- shld edx,eax,cl
- shl eax,cl
- idiv DWORD PTR es:[bx].NV_z ;/* divide by z
- neg eax ;/* except upside down */
- add eax,DWORD PTR _VS_vsc
- and eax,0FFFFFFFCh ;/* lock to integer */
- mov DWORD PTR es:[bx].NV_ys,eax
-
- cmp eax,DWORD PTR _VS_bottom4
- jle nsbo
- or ch,OBOTTOM
- nsbo:
- cmp eax,DWORD PTR _VS_top4
- jge nsto
- or ch,OTOP
- nsto:
- mov BYTE PTR es:[bx].NV_ocode,ch
- or BYTE PTR es:[bx].NV_persp,80h
-
- skip_perspective:
- movzx ax,BYTE PTR es:[bx].NV_ocode ; return outcode
-
- pop edx
- pop ecx
-
- mov esp,ebp
- pop ebp
- ret
-
- _z_output endp
-
-
-
- ;/*********** CONVERT Z COORD OF VERTEX, SET OUTCODES ********/
-
- ; int z_convert_vertex(VERTEX *vtx);
-
-
- vtx equ DWORD PTR [bp+8] ; arguments
-
- PUBLIC _z_convert_vertex
-
- _z_convert_vertex proc far
-
- push ebp
- mov ebp,esp
-
- push esi
- push edi
-
- les si,DWORD PTR vtx
-
- test BYTE PTR es:[si].V_zxflag,80h
- jnz already_z ; check if already done
-
- mov eax,DWORD PTR _VS_sfac7
- mov edx,DWORD PTR es:[si].V_x
- sub edx,DWORD PTR _VS_iview_x
- imul edx
- mov ebx,eax
- mov edi,edx
-
- mov eax,DWORD PTR _VS_sfac8
- mov edx,DWORD PTR es:[si].V_y
- sub edx,DWORD PTR _VS_iview_y
- imul edx
- add ebx,eax
- adc edi,edx
-
- mov eax,DWORD PTR _VS_sfac9
- mov edx,DWORD PTR es:[si].V_z
- sub edx,DWORD PTR _VS_iview_z
- imul edx
- add ebx,eax
- adc edi,edx
-
- shrd ebx,edi,27 ;29-PRESCALEZ
- adc ebx,0
-
- mov DWORD PTR es:[si].V_cz,ebx
- or BYTE PTR es:[si].V_zxflag,80h
-
- xor ax,ax
- cmp ebx,DWORD PTR _VS_hither4
- jge nonhither
- or al,OHITHER
- nonhither:
- cmp ebx,DWORD PTR _VS_yon4
- jle nonyon
- or al,OYON
- nonyon:
- mov BYTE PTR es:[si].V_zocode,al
- already_z:
- movzx ax,BYTE PTR es:[si].V_zocode
-
- pop edi
- pop esi
-
- mov esp,ebp
- pop ebp
- ret
-
- _z_convert_vertex endp
-
-
- ;/*********** POLYGON BACKFACE TEST ***********/
-
- ; int is_poly_facing(POLY *p);
- ; returns sign of visibility dot product
-
-
- p equ DWORD PTR [bp+8] ; arguments
-
- nx equ DWORD PTR [bp-4] ; locals
- ny equ DWORD PTR [bp-8]
- nz equ DWORD PTR [bp-12]
-
- PUBLIC _is_poly_facing
-
- _is_poly_facing proc far
-
- push ebp
- mov ebp,esp
- sub esp,20
-
- push esi
- push edi
-
- les bx,DWORD PTR p
-
- mov edx,DWORD PTR es:[bx].P_normx ; get normals
- mov eax,DWORD PTR es:[bx].P_normy
- mov DWORD PTR ny,eax
- mov eax,DWORD PTR es:[bx].P_normz
- mov DWORD PTR nz,eax
-
- les bx,DWORD PTR es:[bx].P_points ; get first vertex
- les bx,es:[bx]
-
- mov eax,DWORD PTR es:[bx].V_x ; compute dot product
- sub eax,DWORD PTR _VS_iview_x ; with VP to poly line
- imul edx
- mov esi,eax
- mov edi,edx
-
- mov eax,DWORD PTR es:[bx].V_y
- sub eax,DWORD PTR _VS_iview_y
- imul DWORD PTR ny
- add esi,eax
- adc edi,edx
-
- mov eax,DWORD PTR es:[bx].V_z
- sub eax,DWORD PTR _VS_iview_z
- imul DWORD PTR nz
- add esi,eax
- adc edi,edx
- mov ax,-1
- jl proceed
- mov ax,0
- je proceed
- mov ax,1
-
- proceed:
- pop edi
- pop esi
-
- mov esp,ebp
- pop ebp
- ret
-
- _is_poly_facing endp
-
-
-
- ;/*********** CLIP HITHER Z COORD OF VERTEX ***********/
-
- ; creates new vertex from hither plane intercept of edge
- ; allocates new vertex
- ;
- ; NVERTEX *z_hither_clip(NVERTEX *v1, NVERTEX *v2);
-
-
- v1 equ DWORD PTR [bp+8] ; arguments
- v2 equ DWORD PTR [bp+12]
-
- x1 equ DWORD PTR [bp-4] ; locals
- y1 equ DWORD PTR [bp-8]
- z1 equ DWORD PTR [bp-12]
- x2 equ DWORD PTR [bp-16]
- y2 equ DWORD PTR [bp-20]
- z2 equ DWORD PTR [bp-24]
-
- PUBLIC _z_hither_clip
-
- _z_hither_clip proc far
-
- push ebp
- mov ebp,esp
- sub esp,30
-
- push ecx
-
- les bx,DWORD PTR v1
- mov eax, es:[bx].NV_x
- mov DWORD PTR x1,eax
- mov eax, es:[bx].NV_y
- mov DWORD PTR y1,eax
- mov eax, es:[bx].NV_z
- mov DWORD PTR z1,eax
-
- les bx,DWORD PTR v2
- mov eax, es:[bx].NV_x
- mov DWORD PTR x2,eax
- mov eax, es:[bx].NV_y
- mov DWORD PTR y2,eax
- mov eax, es:[bx].NV_z
- mov DWORD PTR z2,eax
-
- ALLOCVTX ; returns new vertex in es:bx
- ; also in _nvalloc
-
- mov ecx,z1 ;/* compute denominator */
- sub ecx,z2
- je zero_clipz ; zero!
- jg other_way ; always clip in same direction
-
- mov eax, _VS_hither4 ;/* compute new x */
- sub eax,z2
- mov edx,x1
- sub edx,x2
- imul edx
- idiv ecx
- add eax,x2
- mov es:[bx].NV_x,eax
-
- mov eax, _VS_hither4 ;/* compute new y */
- sub eax,z2
- mov edx,y1
- sub edx,y2
- imul edx
- idiv ecx
- add eax,y2
- mov es:[bx].NV_y,eax
- jmp endclipz
-
- other_way:
- neg ecx
-
- mov eax, _VS_hither4 ;/* compute new x */
- sub eax,z1
- mov edx,x2
- sub edx,x1
- imul edx
- idiv ecx
- add eax,x1
- mov es:[bx].NV_x,eax
-
- mov eax, _VS_hither4 ;/* compute new y */
- sub eax,z1
- mov edx,y2
- sub edx,y1
- imul edx
- idiv ecx
- add eax,y1
- mov es:[bx].NV_y,eax
- jmp endclipz
-
-
- zero_clipz:
- mov eax,x1
- mov es:[bx].NV_x,eax
- mov eax,y1
- mov es:[bx].NV_y,eax
- endclipz:
- mov eax,DWORD PTR _VS_hither4
- mov DWORD PTR es:[bx].NV_z,eax
-
- mov eax,_nvalloc
- shld edx,eax,16
-
- pop ecx
-
- mov esp,ebp
- pop ebp
- ret
-
- _z_hither_clip endp
-
-
-
- ;/************ COMPUTE AVERAGE DEPTH ************/
-
- ; long average_nvertex_depth(NVERTEX **nvp, int ncount);
- ; retruns average poly depth
-
- nvp equ DWORD PTR [bp+8]
- ncount equ WORD PTR [bp+12]
-
- PUBLIC _average_nvertex_depth
-
- _average_nvertex_depth proc far
-
- push ebp
- mov ebp,esp
-
- push ecx
-
- mov cx,ncount
- nextvtx:
- les bx,nvp
- add WORD PTR nvp,4
- les bx,DWORD PTR es:[bx]
- add eax,es:[bx].NV_z
- adc edx,0
- dec cx
- jg nextvtx
-
- movzx ecx,WORD PTR ncount
- idiv ecx
-
- shld edx,eax,16
-
- pop ecx ; prescaled depth, x4
-
- mov esp,ebp
- pop ebp
- ret
-
- _average_nvertex_depth endp
-
-
- ;/************ COMPUTE MAXIMUM DEPTH ************/
-
- ; long deepest_nvertex_depth(NVERTEX **nvp, int ncount);
- ; retruns average poly depth
-
- nvp equ DWORD PTR [bp+8]
- ncount equ WORD PTR [bp+12]
-
- PUBLIC _deepest_nvertex_depth
-
- _deepest_nvertex_depth proc far
-
- push ebp
- mov ebp,esp
-
- mov dx,ncount
- mov eax,080000001h ; big negative
- nextdvtx:
- les bx,nvp
- add WORD PTR nvp,4
- les bx,DWORD PTR es:[bx]
- cmp eax,es:[bx].NV_z
- jge nodeeper
- mov eax,es:[bx].NV_z
- nodeeper:
- dec dx
- jg nextdvtx
-
- shld edx,eax,16
-
- mov esp,ebp ; prescaled depth, x4
- pop ebp
- ret
-
- _deepest_nvertex_depth endp
-
-
-
- end
-